package com.xbongbong.pro.message.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushSetEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.wrap.Entity;
import com.xbongbong.pro.message.constant.MessageSetDetailTitleConstants;
import com.xbongbong.pro.message.enums.PushObjectTypeEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.pojo.MessageSetDetailPojo;
import com.xbongbong.pro.message.pojo.dto.MessageSetDetailDTO;
import com.xbongbong.pro.message.pojo.vo.MessageSetDetailVO;
import com.xbongbong.pro.message.pojo.vo.PushSetVO;
import com.xbongbong.pro.message.pushset.WorkOrderPushSet;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.WorkOrderCcModel;
import com.xbongbong.saas.model.WorkOrderFlowUserModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 工单消息推送设置实现类
 *
 * @author LiZhikang
 * @date 2022/11/4 17:05
 */
@Service
public class WorkOrderMessageSetServiceImpl extends AbstractMessageSetService {

    @Resource
    private WorkOrderFlowUserModel workOrderFlowUserModel;
    @Resource
    private WorkOrderCcModel workOrderCcModel;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private ContractUserModel contractUserModel;


    @Override
    public List<String> alias() {
        return Collections.singletonList(XbbRefTypeEnum.WORK_ORDER.getAlias());
    }

    @Override
    public String initSetDetailList() throws Exception {
        return null;
    }

    @Override
    public MessageSetDetailVO getSetDetailList(MessageSetDetailDTO messageSetDetailDTO) throws Exception {
        List<MessageSetDetailPojo> messageSetDetailPojos = new ArrayList<>();
        Integer typeInt = messageSetDetailDTO.getSaasIds().get(0).intValue();
        typeInt = XbbRefTypeEnum.transferBusinessType4Distributor(typeInt, messageSetDetailDTO.getDistributorMark());
        String alias = PushTypeEnum.getByCode(typeInt).getAlias();
        if (!Objects.equals(alias, PushTypeEnum.UNKNOWN.getAlias())) {
            String methodName = "getMessageSetSaas" + alias.substring(0, 1).toUpperCase() + alias.substring(1) + "DetailList";
            Method method = this.getClass().getDeclaredMethod(methodName, String.class, List.class, Integer.class);
            method.invoke(this, messageSetDetailDTO.getCorpid(), messageSetDetailPojos, typeInt);
        }
        return new MessageSetDetailVO(messageSetDetailPojos);
    }


    private void getMessageSetSaasWorkOrderPushDetailList(String corpid, List<MessageSetDetailPojo> messageSetDetailPojos, Integer typeInt) throws IllegalAccessException, XbbException, InstantiationException {
        List<PushTypeEnum> pushTypeEnumList = new ArrayList<>(PushTypeEnum.getAllEnumByType(typeInt));
        List<PushTypeEnum> basePushTypeEnum = new ArrayList<>();
        List<PushTypeEnum> workorderPushTypeEnum = new ArrayList<>();
        for (PushTypeEnum pushTypeEnum : pushTypeEnumList) {
            if (Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_NEW_EXECUTOR.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_NEW_EXECUTED.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_CONFIRM.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_TEAM.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_STAGE_COMPLETE.getSubCode())) {
                basePushTypeEnum.add(pushTypeEnum);
            }
            if (Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_DEL_PUSH.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_COMPLETE.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_CLOSE.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_RESTART.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_TRANSFER.getSubCode()) || Objects.equals(pushTypeEnum.getSubCode(), PushTypeEnum.WORKORDER_ROLLBACK.getSubCode())) {
                workorderPushTypeEnum.add(pushTypeEnum);
            }
        }
        WorkOrderPushSet workOrderPushSet = new WorkOrderPushSet();
        MessageSetDetailPojo baseDetail = new MessageSetDetailPojo();
        baseDetail.setTitle(I18nMessageUtil.getMessage(MessageSetDetailTitleConstants.WORK_ORDER_BASE));
        List<PushSetEntity> basePushSetList = new ArrayList<>();
        for (PushTypeEnum pushTypeEnum : basePushTypeEnum) {
            PushSetEntity pushSetEntity = workOrderPushSet.getPushSet(corpid, pushTypeEnum.getSubCode(), pushSetModel);
            basePushSetList.add(pushSetEntity);
        }
        List<PushSetVO> pushSetVOList = new ArrayList<>();
        BeanUtil.copyPropertiesList(basePushSetList, pushSetVOList, PushSetVO.class);
        baseDetail.setValue(pushSetVOList);
        messageSetDetailPojos.add(baseDetail);

        MessageSetDetailPojo otherDetail = new MessageSetDetailPojo();
        otherDetail.setTitle(I18nMessageUtil.getMessage(MessageSetDetailTitleConstants.WORK_ORDER_STATUS_CHANGE));
        List<PushSetEntity> workOrderPushSetList = new ArrayList<>();
        for (PushTypeEnum pushTypeEnum : workorderPushTypeEnum) {
            PushSetEntity pushSetEntity = workOrderPushSet.getPushSet(corpid, pushTypeEnum.getSubCode(), pushSetModel);
            workOrderPushSetList.add(pushSetEntity);
        }
        List<PushSetVO> otherPushSetVOList = new ArrayList<>();
        BeanUtil.copyPropertiesList(workOrderPushSetList, otherPushSetVOList, PushSetVO.class);
        otherDetail.setValue(otherPushSetVOList);
        messageSetDetailPojos.add(otherDetail);
    }


    @Override
    public List<String> getUserIdListByPushSetRule(String corpid, Integer type, Integer subType, UserEntity userEntity, Entity entity) {
        return distinct(getWorkOrderUserIdList(corpid, subType, userEntity, entity));
    }

    private List<String> getWorkOrderUserIdList(String corpid, Integer subType, UserEntity userEntity, Entity entity) {
        String pushObjectString;
        Set<String> result = new HashSet<>();
        WorkOrderEntity workOrderEntity = (WorkOrderEntity) entity;
        WorkOrderPushSet workOrderPushSet = new WorkOrderPushSet();
        PushSetEntity pushSetEntity = workOrderPushSet.getPushSet(corpid, subType, pushSetModel);

        if (Objects.equals(pushSetEntity.getEnable(), 1)) {
            pushObjectString = pushSetEntity.getPushObject();
            JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectString);
            String typeString = pushObject.getString("type");
            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
            for (Object object : typeJsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                Integer enable = jsonObject.getInteger("enable");
                if (Objects.equals(enable, 1)) {
                    JSONObject dataObject = JsonHelperUtil.getJSONObject(workOrderEntity.getData());
                    String alias = jsonObject.getString("alias");
                    if (Objects.equals(alias, PushObjectTypeEnum.CREATOR.getAlias())) {
                        result.add(workOrderEntity.getCreatorId());
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                        result.addAll(workOrderFlowUserModel.getTeamUserIdList(workOrderEntity.getId(), corpid, 1));
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                        result.addAll(workOrderFlowUserModel.getTeamUserIdList(workOrderEntity.getId(), corpid, 0));
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.COPYER.getAlias())) {
                        result.addAll(workOrderCcModel.getUserIds(corpid, workOrderEntity.getId()));
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.CUSTOMERMAINUSER.getAlias())) {
                        Long customerId = dataObject.getLong(WorkOrderEnum.LINK_CUSTOMER.getAttr());
                        if (customerId != null) {
                            result.addAll(customerUserModel.getCustomerUserIdList(corpid, Collections.singletonList(customerId), 1));
                        }
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.CONTRACTMAINUSER.getAlias())) {
                        Long contractId = dataObject.getLong(WorkOrderEnum.LINK_CONTRACT.getAttr());
                        if (contractId != null) {
                            result.addAll(contractUserModel.getContractUserIdList(corpid, contractId, 1));
                        }
                    }
                }
            }
            return getPushUserIdList(userEntity, pushObjectString, new ArrayList<>(result), DateUtil.getInt());
        } else {
            return new ArrayList<>();
        }
    }
}
